<template>
  <div class="app-container">
    <!-- 顶部装饰条 -->
    <div class="tech-header-glow"></div>

    <div class="tech-main-container">
      <!-- 搜索区域 -->
      <div class="tech-search-section">
        <div class="search-header">
          <i class="el-icon-search search-icon"></i>
          <h3 class="search-title">数据检索</h3>
        </div>
        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" class="tech-search-form">
          <div class="search-fields">
            <el-form-item label="病虫害名称" prop="diseaseName">
              <el-input
                v-model="queryParams.diseaseName"
                placeholder="请输入病虫害名称"
                clearable
                @keyup.enter.native="handleQuery"
                class="tech-input"
              />
            </el-form-item>
            <el-form-item label="设备ID" prop="deviceId">
              <el-input
                v-model="queryParams.deviceId"
                placeholder="请输入设备ID"
                clearable
                @keyup.enter.native="handleQuery"
                class="tech-input"
              />
            </el-form-item>
            <el-form-item>
              <el-button class="tech-search-btn" icon="el-icon-search" size="mini" @click="handleQuery">
                <i class="el-icon-search"></i>
                智能搜索
              </el-button>
              <el-button class="tech-reset-btn" icon="el-icon-refresh" size="mini" @click="resetQuery">
                <i class="el-icon-refresh"></i>
                重置条件
              </el-button>
            </el-form-item>
          </div>
        </el-form>
      </div>

      <!-- 图片上传和标注区域 -->
      <div class="tech-workflow-section">
        <!-- 上传卡片 -->
        <div class="tech-card upload-card">
          <div class="card-header-tech">
            <div class="header-content">
              <div class="title-section">
                <i class="el-icon-upload2 title-icon"></i>
                <h3 class="card-title">图像上传</h3>
              </div>
            </div>
          </div>

          <div class="card-content">
            <el-form :model="uploadForm" ref="uploadForm" :rules="uploadRules" class="tech-form">
              <div class="form-grid">
                <div class="form-item">
                  <label class="tech-label">设备ID</label>
                  <el-input v-model="uploadForm.deviceId" placeholder="请输入设备ID" class="tech-input-field" />
                </div>
                <div class="form-item">
                  <label class="tech-label">经度</label>
                  <el-input-number
                    v-model="uploadForm.longitude"
                    :precision="6"
                    :step="0.000001"
                    :min="-180"
                    :max="180"
                    placeholder="经度"
                    class="tech-input-field"
                  />
                </div>
                <div class="form-item">
                  <label class="tech-label">纬度</label>
                  <el-input-number
                    v-model="uploadForm.latitude"
                    :precision="6"
                    :step="0.000001"
                    :min="-90"
                    :max="90"
                    placeholder="纬度"
                    class="tech-input-field"
                  />
                </div>
              </div>

              <!-- 修改上传区域，添加预览状态 -->
              <div class="upload-section">
                <label class="tech-label">上传图片</label>
                <div class="tech-upload-area" @click="$refs.uploadInput.click()">
                  <div class="upload-content" :class="{ 'has-file': fileList.length > 0 }">
                    <i class="el-icon-picture-outline upload-main-icon" :class="{ 'has-file': fileList.length > 0 }"></i>
                    <div class="upload-text">
                      <p class="upload-main-text">
                        {{ fileList.length > 0 ? fileList[0].name : '点击或拖拽图片到此处' }}
                      </p>
                      <p class="upload-sub-text">
                        {{ fileList.length > 0 ? `大小: ${formatFileSize(fileList[0].size)}` : '支持 JPG, PNG 格式，最大10MB' }}
                      </p>
                    </div>
                    <input
                      ref="uploadInput"
                      type="file"
                      accept=".jpg,.jpeg,.png,.JPG,.JPEG,.PNG"
                      @change="handleFileChange"
                      style="display: none"
                    />
                  </div>
                </div>
                <!-- 修改文件预览部分，缩小图片尺寸 -->
                <div v-if="fileList.length > 0 && previewImageUrl" class="file-preview">
                  <div class="preview-header">
                    <span>图片预览</span>
                    <el-button size="mini" type="text" @click="clearSelectedFile">
                      <i class="el-icon-close"></i>
                      清除
                    </el-button>
                  </div>
                  <div class="preview-image-container">
                    <img :src="previewImageUrl" alt="预览图片" class="preview-image" />
                  </div>
                  <div class="preview-info">
                    <p><i class="el-icon-document"></i> {{ fileList[0].name }}</p>
                    <p><i class="el-icon-data-line"></i> {{ formatFileSize(fileList[0].size) }}</p>
                    <p class="preview-hint">点击"上传到服务器"后图片将出现在标注区域</p>
                  </div>
                  <div class="preview-image-container">
                    <img :src="currentImageUrl" alt="预览图片" class="preview-image" />
                  </div>
                </div>
                <div class="upload-actions">
                  <el-button class="tech-primary-btn" @click="submitUpload" :loading="uploadLoading" :disabled="fileList.length === 0">
                    <i class="el-icon-upload2"></i>
                    {{ uploadLoading ? '上传中...' : '上传到服务器' }}
                  </el-button>
                  <el-button class="tech-secondary-btn" @click="clearSelectedFile" :disabled="fileList.length === 0">
                    <i class="el-icon-delete"></i>
                    清除选择
                  </el-button>
                </div>
              </div>
            </el-form>
          </div>
        </div>

        <!-- 标注工具卡片 -->
        <div class="tech-card annotation-card">
          <div class="card-header-tech">
            <div class="header-content">
              <div class="title-section">
                <i class="el-icon-edit title-icon"></i>
                <h3 class="card-title">智能标注工具</h3>
              </div>
              <el-button class="clear-btn-tech" type="text" @click="clearAnnotations">
                <i class="el-icon-delete"></i>
                清空标注
              </el-button>
            </div>
          </div>

          <div class="card-content">
            <div v-if="currentImageUrl" class="annotation-content-tech">
              <!-- 标注控制 -->
              <div class="annotation-controls">
                <el-button
                  class="annotation-toggle-btn"
                  :class="{ active: isAnnotating }"
                  @click="toggleAnnotationMode"
                >
                  <i class="el-icon-aim"></i>
                  {{ isAnnotating ? '停止标注' : '开始标注' }}
                  <div class="btn-glow"></div>
                </el-button>
                <el-button
                  class="tech-success-btn"
                  :disabled="annotations.length === 0"
                  @click="saveAnnotations"
                >
                  <i class="el-icon-finished"></i>
                  保存标注
                </el-button>
                <div class="annotation-status">
                  <div class="status-indicator" :class="{ active: isAnnotating }"></div>
                  <span class="status-text">标注模式：{{ isAnnotating ? '开启' : '关闭' }}</span>
                  <div class="status-hint">提示：拖动鼠标绘制矩形框，按Esc退出</div>
                </div>
              </div>

              <!-- 图片标注区域 -->
              <div class="annotation-area-tech">
                <div class="image-container-tech" ref="imageContainer">
                  <img
                    :src="currentImageUrl"
                    alt="标注图片"
                    ref="annotationImage"
                    @load="onImageLoad"
                    @error="onImageError"
                    class="annotation-image"
                  />
                  <canvas
                    ref="annotationCanvas"
                    class="annotation-canvas-tech"
                    @mousedown="handleCanvasMouseDown"
                    @mousemove="handleCanvasMouseMove"
                    @mouseup="handleCanvasMouseUp"
                    @mouseleave="handleCanvasMouseLeave"
                  ></canvas>
                </div>
              </div>

              <!-- 标注列表 -->
              <div v-if="annotations.length > 0" class="annotation-list-tech">
                <div class="list-header">
                  <h4><i class="el-icon-tickets"></i> 标注列表 ({{ annotations.length }})</h4>
                  <el-tag type="primary">请为每个标注框选择类型</el-tag>
                </div>
                <div class="tech-table-container">
                  <el-table :data="annotations" class="tech-table" size="small">
                    <el-table-column label="序号" width="80" align="center">
                      <template slot-scope="scope">
                        <div class="index-badge">{{ scope.$index + 1 }}</div>
                      </template>
                    </el-table-column>
                    <el-table-column label="坐标" width="200">
                      <template slot-scope="scope">
                        <div class="coordinate-display">
                          [{{ scope.row.bbox[0].toFixed(3) }}, {{ scope.row.bbox[1].toFixed(3) }}]
                          <br>
                          [{{ scope.row.bbox[2].toFixed(3) }}, {{ scope.row.bbox[3].toFixed(3) }}]
                        </div>
                      </template>
                    </el-table-column>
                    <el-table-column label="作物类型" width="200">
                      <template slot-scope="scope">
                        <el-select
                          v-model="scope.row.cropType"
                          placeholder="请选择作物类型"
                          @change="handleCropChange(scope.row)"
                          size="mini"
                          class="tech-select"
                        >
                          <el-option
                            v-for="crop in cropList"
                            :key="crop.value"
                            :label="crop.label"
                            :value="crop.value"
                          />
                        </el-select>
                      </template>
                    </el-table-column>
                    <el-table-column label="病虫害类型" width="250">
                      <template slot-scope="scope">
                        <el-select
                          v-model="scope.row.disease"
                          placeholder="请先选择作物类型"
                          size="mini"
                          class="tech-select"
                          :disabled="!scope.row.cropType"
                        >
                          <el-option
                            v-for="disease in getDiseasesByCrop(scope.row.cropType)"
                            :key="disease.value"
                            :label="disease.label"
                            :value="disease.value"
                          />
                        </el-select>
                      </template>
                    </el-table-column>
                    <el-table-column label="操作" width="100" align="center">
                      <template slot-scope="scope">
                        <el-button
                          size="mini"
                          class="tech-danger-btn"
                          @click="removeAnnotation(scope.$index)"
                        >
                          <i class="el-icon-delete"></i>
                        </el-button>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>
              </div>
            </div>
            <div v-else class="empty-state-tech">
              <div class="empty-content">
                <i class="el-icon-picture-outline empty-icon"></i>
                <h4>等待上传图片</h4>
                <p>请先上传图片进行智能标注</p>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 模型训练卡片 -->
      <div class="tech-card training-card">
        <div class="card-header-tech">
          <div class="header-content">
            <div class="title-section">
              <i class="el-icon-cpu title-icon"></i>
              <h3 class="card-title">AI模型训练</h3>
            </div>
            <el-button class="history-btn-tech" type="text" @click="showTrainingHistory">
              <i class="el-icon-time"></i>
              训练历史
            </el-button>
          </div>
        </div>

        <div class="card-content">
          <el-form :model="trainForm" ref="trainForm" class="tech-form">
            <div class="form-grid-three">
              <div class="form-item">
                <label class="tech-label">训练任务名称</label>
                <el-input v-model="trainForm.taskName" placeholder="请输入训练任务名称" class="tech-input-field" />
              </div>
              <div class="form-item">
                <label class="tech-label">训练描述</label>
                <el-input v-model="trainForm.description" placeholder="请输入训练描述" class="tech-input-field" />
              </div>
              <div class="form-item">
                <label class="tech-label">模型类型</label>
                <el-select v-model="trainForm.modelType" placeholder="请选择模型类型" class="tech-select-field">
                  <el-option label="PP-YOLOE增量学习" value="ppyoloe_incremental" />
                  <el-option label="PP-YOLOE标准训练" value="ppyoloe_standard" />
                </el-select>
              </div>
            </div>

            <div class="form-grid-three">
              <div class="form-item">
                <label class="tech-label">训练轮数</label>
                <el-input-number
                  v-model="trainForm.epochs"
                  :min="10"
                  :max="200"
                  :step="10"
                  placeholder="训练轮数"
                  class="tech-input-field"
                />
              </div>
              <div class="form-item">
                <label class="tech-label">学习率</label>
                <el-input-number
                  v-model="trainForm.learningRate"
                  :min="0.0001"
                  :max="0.01"
                  :step="0.0001"
                  :precision="4"
                  placeholder="学习率"
                  class="tech-input-field"
                />
              </div>
              <div class="form-item">
                <label class="tech-label">批大小</label>
                <el-input-number
                  v-model="trainForm.batchSize"
                  :min="1"
                  :max="32"
                  :step="1"
                  placeholder="批大小"
                  class="tech-input-field"
                />
              </div>
            </div>

            <div class="training-actions">
              <el-button
                class="tech-primary-btn train-btn"
                @click="startTraining"
                :loading="trainingLoading"
                :disabled="!hasAnnotationsForTraining"
              >
                <i class="el-icon-video-play"></i>
                {{ trainingLoading ? '训练中...' : '开始训练' }}
              </el-button>
              <el-button class="tech-secondary-btn" @click="resetTrainForm">
                <i class="el-icon-refresh"></i>
                重置
              </el-button>
              <el-button class="tech-success-btn" @click="exportAnnotations" :loading="exportLoading">
                <i class="el-icon-download"></i>
                导出标注数据
              </el-button>
              <el-button class="tech-warning-btn" @click="diagnoseSystem">
                <i class="el-icon-warning"></i>
                系统诊断
              </el-button>

              <div class="training-status">
                <div class="status-tag" :class="trainingStatus">
                  <div class="status-dot"></div>
                  {{ getTrainingStatusText(trainingStatus) }}
                </div>
              </div>
            </div>

            <!-- 训练进度 -->
            <div v-if="trainingProgress.visible" class="training-progress-tech">
              <div class="progress-header">
                <h4><i class="el-icon-data-line"></i> 训练进度</h4>
                <span class="progress-percentage">{{ trainingProgress.percentage }}%</span>
              </div>
              <div class="progress-bar-container">
                <div class="progress-bar">
                  <div
                    class="progress-fill"
                    :style="{ width: trainingProgress.percentage + '%' }"
                    :class="trainingProgress.status"
                  ></div>
                </div>
              </div>
              <div class="progress-info-tech">
                <div class="info-item">
                  <span class="info-label">当前阶段:</span>
                  <span class="info-value">{{ trainingProgress.currentStage }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">预计剩余时间:</span>
                  <span class="info-value">{{ trainingProgress.estimatedTime }}</span>
                </div>
                <div v-if="currentTrainingTask" class="info-item">
                  <span class="info-label">任务ID:</span>
                  <span class="info-value">{{ currentTrainingTask.id }}</span>
                </div>
              </div>

              <div class="progress-actions">
                <el-button size="mini" class="tech-danger-btn" @click="stopTraining">
                  <i class="el-icon-switch-button"></i>
                  停止训练
                </el-button>
                <el-button size="mini" class="tech-info-btn" @click="viewTrainingLog">
                  <i class="el-icon-document"></i>
                  查看日志
                </el-button>
              </div>
            </div>
          </el-form>
        </div>
      </div>

      <!-- 数据列表 -->
      <div class="tech-data-section">
        <div class="section-header-tech">
          <h3 class="section-title">
            <i class="el-icon-collection"></i>
            标注数据管理
          </h3>
          <div class="action-buttons-tech">
            <el-button class="action-btn add-btn" icon="el-icon-plus" size="mini" @click="handleAdd">
              <span class="button-text">新增</span>
            </el-button>
            <el-button class="action-btn edit-btn" icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate">
              <span class="button-text">修改</span>
            </el-button>
            <el-button class="action-btn delete-btn" icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete">
              <span class="button-text">删除</span>
            </el-button>
            <el-button class="action-btn export-btn" icon="el-icon-download" size="mini" @click="handleExport">
              <span class="button-text">导出</span>
            </el-button>
          </div>
        </div>

        <div class="tech-table-container">
          <el-table
            v-loading="loading"
            :data="diseaseLabelList"
            @selection-change="handleSelectionChange"
            class="tech-data-table"
            :header-cell-style="headerCellStyle"
            :cell-style="cellStyle"
          >
            <el-table-column type="selection" width="55" align="center" />
            <el-table-column label="ID" align="center" prop="id" width="80">
              <template slot-scope="scope">
                <div class="id-cell">{{ scope.row.id }}</div>
              </template>
            </el-table-column>
            <el-table-column label="标注结果" align="center" width="140">
              <template slot-scope="scope">
                <div class="image-cell" @click="previewAnnotatedImage(scope.row)">
                  <div class="image-container">
                    <el-image
                      :src="getAnnotatedImageUrl(scope.row)"
                      :preview-src-list="[getAnnotatedImageUrl(scope.row)]"
                      fit="cover"
                      class="table-image"
                    >
                      <div slot="error" class="image-slot">
                        <i class="el-icon-picture-outline"></i>
                      </div>
                    </el-image>
                    <div v-if="!getAnnotatedImageUrl(scope.row)" class="image-placeholder">
                      <i class="el-icon-picture-outline"></i>
                      <span>无图片</span>
                    </div>
                    <div class="image-overlay">
                      <i class="el-icon-zoom-in"></i>
                    </div>
                    <div class="image-status" :class="{ annotated: hasAnnotations(scope.row) }">
                      {{ hasAnnotations(scope.row) ? '已标注' : '未标注' }}
                    </div>
                  </div>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="病虫害名称" align="center" prop="diseaseName">
              <template slot-scope="scope">
                <div class="disease-cell">
                  <span class="disease-name">{{ scope.row.diseaseName || '-' }}</span>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="作物类型" align="center" prop="cropType">
              <template slot-scope="scope">
                <div class="crop-cell">
                  {{ scope.row.cropType || '-' }}
                </div>
              </template>
            </el-table-column>
            <el-table-column label="设备ID" align="center" prop="deviceId">
              <template slot-scope="scope">
                <div class="device-cell">
                  {{ scope.row.deviceId || '-' }}
                </div>
              </template>
            </el-table-column>
            <el-table-column label="标注数量" align="center" width="120">
              <template slot-scope="scope">
                <div class="annotation-count" :class="{
            empty: getAnnotationCount(scope.row) === 0,
            high: getAnnotationCount(scope.row) > 5,
            medium: getAnnotationCount(scope.row) > 0 && getAnnotationCount(scope.row) <= 5
          }">
                  {{ getAnnotationCount(scope.row) || 0 }} 个
                </div>
              </template>
            </el-table-column>
            <el-table-column label="坐标" align="center" width="180">
              <template slot-scope="scope">
                <div class="coordinate-display">
                  <div class="coordinate-item">
                    <span class="coordinate-label">经度:</span>
                    <span class="coordinate-value" v-if="scope.row.gpsLongitude">
                {{ scope.row.gpsLongitude.toFixed(6) }}
              </span>
                    <span v-else class="no-data">-</span>
                  </div>
                  <div class="coordinate-item">
                    <span class="coordinate-label">纬度:</span>
                    <span class="coordinate-value" v-if="scope.row.gpsLatitude">
                {{ scope.row.gpsLatitude.toFixed(6) }}
              </span>
                    <span v-else class="no-data">-</span>
                  </div>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="操作" align="center" width="280">
              <template slot-scope="scope">
                <div class="action-buttons">
                  <el-button
                    size="mini"
                    class="action-btn view-btn"
                    @click="viewAnnotations(scope.row)"
                  >
                    <i class="el-icon-picture"></i>
                    <span>标注</span>
                  </el-button>
                  <el-button
                    size="mini"
                    class="action-btn edit-btn"
                    @click="handleUpdate(scope.row)"
                  >
                    <i class="el-icon-edit"></i>
                    <span>修改</span>
                  </el-button>
                  <el-button
                    size="mini"
                    class="action-btn delete-btn"
                    @click="handleDelete(scope.row)"
                  >
                    <i class="el-icon-delete"></i>
                    <span>删除</span>
                  </el-button>
                  <el-button
                    size="mini"
                    class="action-btn preview-btn"
                    @click="previewAnnotatedImage(scope.row)"
                  >
                    <i class="el-icon-view"></i>
                    <span>预览</span>
                  </el-button>
                </div>
              </template>
            </el-table-column>
          </el-table>
        </div>

        <!-- 分页 -->
        <div class="pagination-section" v-show="total>0">
          <pagination
            :total="total"
            :page.sync="queryParams.pageNum"
            :limit.sync="queryParams.pageSize"
            @pagination="getList"
            class="history-pagination"
          />
        </div>
      </div>
    </div>

    <!-- 各种对话框保持不变，只修改样式 -->
    <!-- 标注结果图片预览对话框 -->
    <el-dialog :title="previewTitle" :visible.sync="imagePreviewVisible" width="70%" class="tech-dialog">
      <div style="text-align: center;">
        <img :src="previewImageUrl" style="max-width: 100%; max-height: 70vh;" :alt="previewTitle" />
        <div style="margin-top: 10px; color: #ccddff;">
          <p v-if="currentPreviewRow">{{ getImageDescription(currentPreviewRow) }}</p>
          <p v-if="currentPreviewRow && getAnnotationCount(currentPreviewRow) > 0">
            包含 {{ getAnnotationCount(currentPreviewRow) }} 个标注
          </p>
        </div>
      </div>
    </el-dialog>

    <!-- 查看标注对话框 -->
    <el-dialog title="标注详情" :visible.sync="annotationDialogVisible" width="800px" class="tech-dialog">
      <div v-if="currentAnnotationData">
        <el-tabs type="border-card" class="tech-tabs">
          <el-tab-pane label="标注信息">
            <json-viewer :value="currentAnnotationData" :expand-depth="3" copyable></json-viewer>
          </el-tab-pane>
          <el-tab-pane label="原始数据">
            <pre>{{ JSON.stringify(currentAnnotationData, null, 2) }}</pre>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-dialog>

    <!-- 训练历史对话框 -->
    <el-dialog title="训练历史" :visible.sync="trainingHistoryVisible" width="80%" class="tech-dialog">
      <el-table :data="trainingHistory" v-loading="historyLoading" class="tech-table">
        <!-- 表格列定义保持不变 -->
      </el-table>
    </el-dialog>

    <!-- 训练日志对话框 -->
    <el-dialog title="训练日志" :visible.sync="trainingLogVisible" width="90%" class="tech-dialog">
      <div class="log-container-tech">
        <pre>{{ trainingLog }}</pre>
      </div>
    </el-dialog>

    <!-- 诊断结果对话框 -->
    <el-dialog title="系统诊断结果" :visible.sync="diagnoseVisible" width="80%" class="tech-dialog">
      <!-- 诊断内容保持不变 -->
    </el-dialog>
  </div>
</template>

<script>
import {
  listDiseaseLabel,
  getDiseaseLabel,
  delDiseaseLabel,
  addDiseaseLabel,
  updateDiseaseLabel,
  uploadImage,
  saveAnnotations,
  // 训练相关API
  startTraining,
  stopTraining,
  getTrainingStatus,
  getTrainingHistory,
  getTrainingLog,
  downloadModel,
  exportUserAnnotations,
  diagnoseSystem,
  debugTrainingEnvironment,
  testSimpleTraining,
  splitDataset
} from "@/api/insect/label"
import { getToken } from "@/utils/auth"
import { parseTime } from "@/utils/ruoyi"

export default {
  name: "DiseaseLabel",
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 数据标注表格数据
      diseaseLabelList: [],
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        diseaseName: null,
        deviceId: null
      },

      // 上传相关
      uploadForm: {
        deviceId: '',
        longitude: null,
        latitude: null
      },
      filePreviewUrl: '', // 添加文件预览URL
      uploadRules: {
        deviceId: [
          { required: true, message: '设备ID不能为空', trigger: 'blur' }
        ]
      },
      fileList: [],
      uploadLoading: false,
      uploadAction: process.env.VUE_APP_BASE_API + '/insect/diseaselabel/upload',
      uploadHeaders: {
        'Authorization': 'Bearer ' + getToken()
      },

      // 标注相关
      currentImageUrl: '',
      currentLabelId: null,

      // 作物和病虫害数据
      cropList: [
        { value: 'apple', label: '苹果' },
        { value: 'bell_pepper', label: '甜椒' },
        { value: 'blueberry', label: '蓝莓' },
        { value: 'cherry', label: '樱桃' },
        { value: 'corn', label: '玉米' },
        { value: 'peach', label: '桃' },
        { value: 'potato', label: '马铃薯' },
        { value: 'raspberry', label: '树莓' },
        { value: 'soybean', label: '大豆' },
        { value: 'squash', label: '西葫芦' },
        { value: 'strawberry', label: '草莓' },
        { value: 'tomato', label: '番茄' },
        { value: 'grape', label: '葡萄' }
      ],

      // 作物-病虫害映射
      cropDiseaseMap: {
        'apple': [
          { value: 'apple_scab_leaf', label: '苹果黑星病叶' },
          { value: 'apple_leaf', label: '苹果叶' },
          { value: 'apple_rust_leaf', label: '苹果锈病叶' }
        ],
        'bell_pepper': [
          { value: 'bell_pepper_leaf', label: '甜椒叶' },
          { value: 'bell_pepper_leaf_spot', label: '甜椒叶斑病' }
        ],
        'blueberry': [
          { value: 'blueberry_leaf', label: '蓝莓叶' }
        ],
        'cherry': [
          { value: 'cherry_leaf', label: '樱桃叶' }
        ],
        'corn': [
          { value: 'corn_gray_leaf_spot', label: '玉米灰斑病' },
          { value: 'corn_leaf_blight', label: '玉米叶枯病' },
          { value: 'corn_rust_leaf', label: '玉米锈病叶' }
        ],
        'peach': [
          { value: 'peach_leaf', label: '桃叶' }
        ],
        'potato': [
          { value: 'potato_leaf', label: '马铃薯叶' },
          { value: 'potato_leaf_early_blight', label: '马铃薯早疫病' },
          { value: 'potato_leaf_late_blight', label: '马铃薯晚疫病' }
        ],
        'raspberry': [
          { value: 'raspberry_leaf', label: '树莓叶' }
        ],
        'soybean': [
          { value: 'soybean_leaf', label: '大豆叶' }
        ],
        'squash': [
          { value: 'squash_powdery_mildew_leaf', label: '西葫芦白粉病叶' }
        ],
        'strawberry': [
          { value: 'strawberry_leaf', label: '草莓叶' }
        ],
        'tomato': [
          { value: 'tomato_early_blight_leaf', label: '番茄早疫病叶' },
          { value: 'tomato_septoria_leaf_spot', label: '番茄斑枯病叶' },
          { value: 'tomato_leaf', label: '番茄叶' },
          { value: 'tomato_leaf_bacterial_spot', label: '番茄细菌性斑点病叶' },
          { value: 'tomato_leaf_late_blight', label: '番茄晚疫病叶' },
          { value: 'tomato_leaf_mosaic_virus', label: '番茄花叶病毒病叶' },
          { value: 'tomato_leaf_yellow_virus', label: '番茄黄化病毒病叶' },
          { value: 'tomato_mold_leaf', label: '番茄霉叶' },
          { value: 'tomato_two_spotted_spider_mites_leaf', label: '番茄二斑叶螨叶' }
        ],
        'grape': [
          { value: 'grape_leaf', label: '葡萄叶' },
          { value: 'grape_leaf_black_rot', label: '葡萄黑腐病叶' }
        ]
      },

      annotations: [],
      isAnnotating: false,

      // 图片预览相关
      imagePreviewVisible: false,
      previewImageUrl: '',
      previewTitle: '',
      currentPreviewRow: null,

      // 标注绘制状态
      isDrawing: false,
      startPos: { x: 0, y: 0 },
      currentRect: null,

      // 添加诊断相关的属性
      diagnoseVisible: false,
      diagnoseResult: null,

      // 画布尺寸
      canvasWidth: 0,
      canvasHeight: 0,

      // 标注对话框
      annotationDialogVisible: false,
      currentAnnotationData: null,

      // 表单参数
      form: {},
      open: false,
      title: "",
      rules: {
        deviceId: [
          { required: true, message: "设备ID不能为空", trigger: "blur" }
        ]
      },

      // ==================== 训练相关数据 ====================
      // 训练表单
      trainForm: {
        taskName: '',
        description: '',
        epochs: 50,
        learningRate: 0.001,
        batchSize: 8,
        modelType: 'ppyoloe_incremental',
        usePretrained: true
      },
      trainingLoading: false,
      exportLoading: false,
      trainingStatus: '', // running, completed, failed, stopped
      currentTrainingTask: null,

      // 训练进度
      trainingProgress: {
        visible: false,
        percentage: 0,
        status: 'success',
        currentStage: '',
        estimatedTime: ''
      },

      // 训练历史
      trainingHistoryVisible: false,
      trainingHistory: [],
      historyLoading: false,

      // 训练日志
      trainingLogVisible: false,
      trainingLog: '',
      logLoading: false,
      currentLogTask: null,

      // 轮询定时器
      trainingStatusTimer: null
    }
  },
  computed: {
    // 检查是否有足够的标注数据用于训练
    hasAnnotationsForTraining() {
      return this.diseaseLabelList.some(row => this.hasAnnotations(row))
    }
  },
  created() {
    this.getList()
  },
  mounted() {
    // 添加键盘事件监听
    document.addEventListener('keydown', this.handleKeyDown)
    // 添加窗口resize监听
    window.addEventListener('resize', this.handleResize)
  },
  beforeDestroy() {
    // 移除事件监听
    document.removeEventListener('keydown', this.handleKeyDown)
    window.removeEventListener('resize', this.handleResize)
    // 清除轮询定时器
    if (this.trainingStatusTimer) {
      clearInterval(this.trainingStatusTimer)
    }
  },
  methods: {
    startProgressSimulation() {
      console.log('模拟进度启动了（空实现）');
    },
    // 表头样式
    headerCellStyle() {
      return {
        background: 'linear-gradient(135deg, rgba(22, 33, 62, 0.9) 0%, rgba(15, 52, 96, 0.9) 100%)',
        color: '#ffffff',
        borderBottom: '1px solid rgba(0, 255, 255, 0.2)',
        fontWeight: '600',
        fontSize: '14px'
      }
    },

// 单元格样式
    cellStyle() {
      return {
        background: 'rgba(20, 25, 45, 0.6)',
        color: '#e0e0ff',
        borderBottom: '1px solid rgba(0, 150, 255, 0.1)',
        fontSize: '13px'
      }
    },
    /** 查询数据标注列表 */
    getList() {
      this.loading = true
      listDiseaseLabel(this.queryParams).then(response => {
        this.diseaseLabelList = response.rows
        this.total = response.total
        this.loading = false
      }).catch(() => {
        this.loading = false
      })
    },

    // 修改文件选择处理 - 只设置预览，不设置标注图片
    handleFileChange(event) {
      const file = event.target.files[0];
      if (!file) {
        this.$message.warning('未选择文件');
        return;
      }

      // 验证文件类型
      const validTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/JPG', 'image/JPEG', 'image/PNG'];
      if (!validTypes.includes(file.type)) {
        this.$message.error('请选择 JPG 或 PNG 格式的图片文件');
        this.clearFileInput();
        return;
      }

      // 验证文件大小 (10MB)
      const maxSize = 10 * 1024 * 1024;
      if (file.size > maxSize) {
        this.$message.error('图片大小不能超过 10MB');
        this.clearFileInput();
        return;
      }

      // 更新文件列表（只保留一个文件）
      this.fileList = [{
        raw: file,
        name: file.name,
        size: file.size
      }];

      // 只设置预览URL，不设置标注URL
      if (this.previewImageUrl) {
        URL.revokeObjectURL(this.previewImageUrl);
      }

      this.previewImageUrl = URL.createObjectURL(file);

      // 重置标注状态（保持标注区域为空）
      this.currentImageUrl = '';
      this.annotations = [];
      this.isAnnotating = false;
      this.currentLabelId = null;

      console.log('文件选择成功:', file.name, '大小:', this.formatFileSize(file.size));
      this.$message.success(`已选择图片: ${file.name}`);

      // 注意：这里不初始化画布，因为图片还没有上传到标注区域
    },

// 添加清除文件输入的方法
    clearFileInput() {
      if (this.$refs.uploadInput) {
        this.$refs.uploadInput.value = '';
      }
      this.fileList = [];
    },

// 添加文件大小格式化方法
    formatFileSize(bytes) {
      if (bytes === 0) return '0 B';
      const k = 1024;
      const sizes = ['B', 'KB', 'MB', 'GB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    },

    // 清除选择的文件
    clearSelectedFile() {
      this.fileList = [];
      this.clearFileInput();
      if (this.previewImageUrl) {
        URL.revokeObjectURL(this.previewImageUrl);
        this.previewImageUrl = '';
      }
      this.$message.info('已清除选择的文件');
    },

// 修改上传方法 - 上传成功后才设置标注图片
    async submitUpload() {
      this.$refs.uploadForm.validate((valid) => {
        if (valid) {
          if (this.fileList.length === 0) {
            this.$message.error('请先选择图片');
            return;
          }

          this.uploadLoading = true;

          const formData = new FormData();
          formData.append('file', this.fileList[0].raw);
          formData.append('deviceId', this.uploadForm.deviceId);

          if (this.uploadForm.longitude) {
            formData.append('longitude', this.uploadForm.longitude);
          }
          if (this.uploadForm.latitude) {
            formData.append('latitude', this.uploadForm.latitude);
          }

          console.log('开始上传文件:', this.fileList[0].name);
          console.log('设备ID:', this.uploadForm.deviceId);

          uploadImage(formData).then(response => {
            this.uploadLoading = false;
            if (response.code === 200) {
              this.$message.success('上传成功');

              // 设置当前图片和labelId - 只在标注区域显示
              const { fileName, labelId } = response.data;
              this.currentImageUrl = this.getImageUrl(fileName); // 设置标注区域图片
              this.currentLabelId = labelId;

              // 清空预览图片
              if (this.previewImageUrl) {
                URL.revokeObjectURL(this.previewImageUrl);
                this.previewImageUrl = '';
              }

              // 清空上传表单
              this.uploadForm.deviceId = '';
              this.uploadForm.longitude = null;
              this.uploadForm.latitude = null;
              this.fileList = [];
              this.clearFileInput();

              // 刷新列表
              this.getList();

              this.$message.success('图片上传成功，可以开始标注了');

              // 初始化标注区域的画布
              this.$nextTick(() => {
                setTimeout(() => {
                  this.initCanvas();
                }, 500);
              });
            } else {
              this.$message.error(response.msg || '上传失败');
            }
          }).catch(error => {
            this.uploadLoading = false;
            console.error('上传失败:', error);
            let errorMessage = '上传失败: ';
            if (error.response && error.response.data) {
              errorMessage += error.response.data.msg || error.response.data.message;
            } else {
              errorMessage += error.message || '未知错误';
            }
            this.$message.error(errorMessage);
          });
        } else {
          this.$message.error('请填写正确的设备ID');
        }
      });
    },

    // 标注相关方法
    toggleAnnotationMode() {
      this.isAnnotating = !this.isAnnotating
      if (this.isAnnotating) {
        this.$message.success('标注模式已开启，请在图片上拖动绘制矩形框')
      } else {
        this.$message.info('标注模式已关闭')
      }
    },

    onImageLoad() {
      const img = this.$refs.annotationImage
      if (img) {
        setTimeout(() => {
          this.initCanvas()
        }, 100)
      }
    },

    onImageError() {
      this.$message.error('图片加载失败，请检查图片路径')
    },

    // 初始化画布
    initCanvas() {
      const canvas = this.$refs.annotationCanvas
      const img = this.$refs.annotationImage

      if (!canvas || !img) {
        return
      }

      // 获取图片的显示尺寸
      const imgRect = img.getBoundingClientRect()
      this.canvasWidth = imgRect.width
      this.canvasHeight = imgRect.height

      // 设置画布尺寸
      canvas.width = this.canvasWidth
      canvas.height = this.canvasHeight

      // 设置画布样式
      canvas.style.width = this.canvasWidth + 'px'
      canvas.style.height = this.canvasHeight + 'px'

      this.redrawCanvas()
    },

    // 鼠标事件处理
    handleCanvasMouseDown(event) {
      if (!this.isAnnotating) {
        return
      }

      const canvas = this.$refs.annotationCanvas
      const rect = canvas.getBoundingClientRect()

      // 计算鼠标在画布内的坐标
      const x = event.clientX - rect.left
      const y = event.clientY - rect.top

      this.isDrawing = true
      this.startPos = { x, y }

      this.currentRect = {
        x: x,
        y: y,
        width: 0,
        height: 0
      }
    },

    handleCanvasMouseMove(event) {
      if (!this.isDrawing || !this.currentRect) return

      const canvas = this.$refs.annotationCanvas
      const rect = canvas.getBoundingClientRect()
      const currentX = event.clientX - rect.left
      const currentY = event.clientY - rect.top

      // 更新当前矩形尺寸
      this.currentRect.width = currentX - this.startPos.x
      this.currentRect.height = currentY - this.startPos.y

      // 重绘画布
      this.redrawCanvas()

      // 绘制当前矩形
      this.drawCurrentRect()
    },

    handleCanvasMouseUp(event) {
      if (!this.isDrawing || !this.currentRect) return

      const canvas = this.$refs.annotationCanvas
      const rect = canvas.getBoundingClientRect()
      const currentX = event.clientX - rect.left
      const currentY = event.clientY - rect.top

      const width = Math.abs(currentX - this.startPos.x)
      const height = Math.abs(currentY - this.startPos.y)

      // 最小尺寸限制
      if (width > 10 && height > 10) {
        // 计算归一化坐标 [x_min, y_min, x_max, y_max]
        const x_min = Math.min(this.startPos.x, currentX) / this.canvasWidth
        const y_min = Math.min(this.startPos.y, currentY) / this.canvasHeight
        const x_max = Math.max(this.startPos.x, currentX) / this.canvasWidth
        const y_max = Math.max(this.startPos.y, currentY) / this.canvasHeight

        const bbox = [x_min, y_min, x_max, y_max]

        // 添加标注，初始时作物类型和病虫害类型为空
        this.annotations.push({
          bbox: bbox,
          cropType: '',
          disease: ''
        })

        this.$message.success('标注框添加成功，请在下方选择类型')
      } else {
        this.$message.warning('标注框太小，请绘制更大的区域')
      }

      this.isDrawing = false
      this.currentRect = null
      this.redrawCanvas()
    },

    handleCanvasMouseLeave() {
      if (this.isDrawing) {
        this.isDrawing = false
        this.currentRect = null
        this.redrawCanvas()
      }
    },

    // 绘制当前正在绘制的矩形
    drawCurrentRect() {
      if (!this.currentRect) return

      const canvas = this.$refs.annotationCanvas
      const ctx = canvas.getContext('2d')

      ctx.strokeStyle = '#ff0000'
      ctx.lineWidth = 2
      ctx.setLineDash([5, 5])
      ctx.strokeRect(
        this.currentRect.x,
        this.currentRect.y,
        this.currentRect.width,
        this.currentRect.height
      )
      ctx.setLineDash([])
    },

    // 重绘画布 - 绘制所有标注（只显示序号，不显示类型）
    redrawCanvas() {
      const canvas = this.$refs.annotationCanvas
      if (!canvas) return

      const ctx = canvas.getContext('2d')
      ctx.clearRect(0, 0, canvas.width, canvas.height)

      // 绘制所有已存在的标注
      this.annotations.forEach((annotation, index) => {
        this.drawAnnotation(ctx, annotation, index)
      })
    },

    // 绘制单个标注（只显示序号）
    drawAnnotation(ctx, annotation, index) {
      const [x_min, y_min, x_max, y_max] = annotation.bbox

      // 转换为画布坐标
      const pixelX = x_min * this.canvasWidth
      const pixelY = y_min * this.canvasHeight
      const pixelWidth = (x_max - x_min) * this.canvasWidth
      const pixelHeight = (y_max - y_min) * this.canvasHeight

      // 绘制矩形框
      ctx.strokeStyle = '#00ff00'
      ctx.lineWidth = 2
      ctx.strokeRect(pixelX, pixelY, pixelWidth, pixelHeight)

      // 绘制背景标签（只显示序号）
      ctx.fillStyle = '#00ff00'
      ctx.font = '12px Arial'
      const labelText = `${index + 1}`
      const textMetrics = ctx.measureText(labelText)

      ctx.fillRect(pixelX, pixelY - 15, textMetrics.width + 8, 15)

      // 绘制文字（只显示序号）
      ctx.fillStyle = '#000000'
      ctx.fillText(labelText, pixelX + 4, pixelY - 3)
    },

    // 根据作物类型获取对应的病虫害列表
    getDiseasesByCrop(cropType) {
      return this.cropDiseaseMap[cropType] || []
    },

    // 作物类型改变时的处理
    handleCropChange(row) {
      // 当作物类型改变时，清空之前选择的病虫害
      row.disease = ''
    },

    removeAnnotation(index) {
      this.annotations.splice(index, 1)
      this.redrawCanvas()
      this.$message.success('删除标注成功')
    },

    clearAnnotations() {
      this.annotations = []
      this.redrawCanvas()
      this.$message.info('已清空所有标注')
    },

    // 保存标注 - 关键修改：将disease和cropType合并为category
    saveAnnotations() {
      if (!this.currentLabelId) {
        this.$message.error('请先上传图片')
        return
      }

      if (this.annotations.length === 0) {
        this.$message.error('请先进行标注')
        return
      }

      // 检查所有标注是否都选择了作物类型和病虫害类型
      const incompleteAnnotations = this.annotations.filter(anno =>
        !anno.cropType || !anno.disease
      )

      if (incompleteAnnotations.length > 0) {
        this.$message.error(`还有 ${incompleteAnnotations.length} 个标注未选择完整的类型信息`)
        return
      }

      // 构建符合要求的标注数据格式
      // 关键修改：将disease作为category，不再单独存储cropType
      const formattedAnnotations = this.annotations.map(anno => ({
        bbox: anno.bbox,
        category: anno.disease  // 只存储disease信息作为category
      }))

      const requestData = {
        labelId: this.currentLabelId,
        annotations: formattedAnnotations
      }

      console.log('保存标注数据:', requestData)

      saveAnnotations(requestData).then(response => {
        if (response.code === 200) {
          this.$message.success('标注保存成功')
          this.getList()
        } else {
          this.$message.error(response.msg)
        }
      }).catch(error => {
        this.$message.error('保存失败: ' + (error.message || '未知错误'))
      })
    },

    handleKeyDown(e) {
      if (e.key === 'Escape') {
        this.isAnnotating = false
        this.isDrawing = false
        this.currentRect = null
        this.redrawCanvas()
        this.$message.info('已退出标注模式')
      }
    },

    handleResize() {
      if (this.currentImageUrl) {
        setTimeout(() => {
          this.initCanvas()
        }, 300)
      }
    },

    // 图片URL相关方法
    getImageUrl(fileName) {
      if (!fileName) return ''
      if (fileName.startsWith('http')) return fileName
      const baseUrl = process.env.VUE_APP_BASE_API
      return `${baseUrl}/profile/upload/${fileName}`
    },

    // 查看标注
    viewAnnotations(row) {
      if (row.annotationData) {
        try {
          this.currentAnnotationData = JSON.parse(row.annotationData)
          this.annotationDialogVisible = true
        } catch (e) {
          this.$message.error('标注数据格式错误')
        }
      } else {
        this.$message.info('该记录暂无标注数据')
      }
    },

    // 预览标注结果图片
    previewAnnotatedImage(row) {
      this.previewImageUrl = this.getAnnotatedImageUrl(row)
      this.previewTitle = this.getImageDescription(row)
      this.currentPreviewRow = row
      this.imagePreviewVisible = true
    },

    // 获取标注结果图片URL
    getAnnotatedImageUrl(row) {
      let fileName = row.annotatedImage
      if (!fileName && this.hasAnnotations(row)) {
        fileName = row.originalImage
      }
      if (!fileName) {
        fileName = row.originalImage
      }
      if (!fileName) {
        return ''
      }
      const baseUrl = process.env.VUE_APP_BASE_API
      return `${baseUrl}/profile/upload/${fileName}`
    },

    // 检查是否有标注
    hasAnnotations(row) {
      return this.getAnnotationCount(row) > 0
    },

    // 获取标注数量
    getAnnotationCount(row) {
      if (!row.annotationData) {
        return 0
      }
      try {
        const annotationData = JSON.parse(row.annotationData)
        const labels = annotationData.labels
        return labels ? labels.length : 0
      } catch (e) {
        console.error('解析标注数据失败:', e)
        return 0
      }
    },

    // 获取图片描述
    getImageDescription(row) {
      if (row.annotatedImage) {
        return '标注结果图片'
      } else if (this.hasAnnotations(row)) {
        return '已标注（生成中）'
      } else if (row.originalImage) {
        return '原图'
      }
      return '图片'
    },

    // 图片加载错误处理
    handleImageError(row) {
      console.error('图片加载失败:', row)
      this.$message.error('图片加载失败，请检查图片路径')
    },

    // 图片加载成功
    handleImageLoad(row) {
      console.log('图片加载成功:', row)
    },

    // 取消按钮
    cancel() {
      this.open = false
      this.reset()
    },

    // 表单重置
    reset() {
      this.form = {
        id: null,
        originalImage: null,
        diseaseName: null,
        diseaseSymptom: null,
        diseaseSolution: null,
        diseaseType: null,
        cropType: null,
        annotationData: null,
        deviceId: null,
        gpsLongitude: null,
        gpsLatitude: null,
        photoTime: null
      }
      this.resetForm("form")
    },

    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },

    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm")
      this.handleQuery()
    },

    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.single = selection.length !== 1
      this.multiple = !selection.length
    },

    /** 新增按钮操作 */
    handleAdd() {
      this.reset()
      this.open = true
      this.title = "添加数据标注"
    },

    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset()
      const id = row.id || this.ids
      getDiseaseLabel(id).then(response => {
        this.form = response.data
        this.open = true
        this.title = "修改数据标注"
      })
    },

    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          if (this.form.id != null) {
            updateDiseaseLabel(this.form).then(response => {
              this.$modal.msgSuccess("修改成功")
              this.open = false
              this.getList()
            })
          } else {
            addDiseaseLabel(this.form).then(response => {
              this.$modal.msgSuccess("新增成功")
              this.open = false
              this.getList()
            })
          }
        }
      })
    },

    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids
      this.$modal.confirm('是否确认删除数据标注编号为"' + ids + '"的数据项？').then(() => {
        return delDiseaseLabel(ids)
      }).then(() => {
        this.getList()
        this.$modal.msgSuccess("删除成功")
      }).catch(() => {})
    },

    /** 导出按钮操作 */
    handleExport() {
      this.download('insect/diseaselabel/export', {
        ...this.queryParams
      }, `diseaselabel_${new Date().getTime()}.xlsx`)
    },

    parseTime,

    // ==================== 训练相关方法 ====================
// 修改开始训练方法中的加载提示
    startTraining() {
      this.$refs.trainForm.validate(async (valid) => {
        if (valid) {
          if (!this.hasAnnotationsForTraining) {
            this.$message.error('当前没有足够的标注数据，请先进行数据标注')
            return
          }

          // ===== 👇 数据集分割逻辑 =====
          this.trainingProgress.visible = true
          this.trainingProgress.percentage = 2
          this.trainingProgress.currentStage = '正在分割数据集...'
          this.trainingProgress.status = 'success'

          try {
            await splitDataset()
            this.$message.success('数据集分割成功')
          } catch (err) {
            this.$message.error('数据集分割失败，请检查服务端日志')
            this.trainingLoading = false
            this.trainingStatus = 'failed'
            this.trainingProgress.status = 'exception'
            return
          }

          // ===== 👇 原训练逻辑开始 =====
          this.trainingLoading = true
          this.trainingStatus = 'running'
          this.trainingProgress.percentage = 5
          this.trainingProgress.currentStage = '准备训练环境...'
          this.trainingProgress.status = 'success'
          this.trainingProgress.estimatedTime = '计算中...'

          const loadingInstance = this.$loading({
            lock: true,
            text: '正在启动训练任务...',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)'
          });
          console.log('🚀 trainForm 提交内容：', this.trainForm)
          startTraining(this.trainForm).then(trainingResponse => {
            loadingInstance.close();
            if (trainingResponse.code === 200) {
              this.currentTrainingTask = trainingResponse.data
              this.$message.success('训练任务已启动')

              // 开始轮询训练状态
              this.startPollingTrainingStatus()

              // 启动进度模拟（作为后备）
              this.startProgressSimulation()
            } else {
              this.trainingLoading = false
              this.trainingStatus = 'failed'
              this.trainingProgress.status = 'exception'
              this.$message.error(trainingResponse.msg || '训练启动失败')
            }
          }).catch(trainingError => {
            loadingInstance.close();
            this.trainingLoading = false
            this.trainingStatus = 'failed'
            this.trainingProgress.status = 'exception'
            this.$message.error('训练启动失败: ' + (trainingError.message || '未知错误'))
          })
        }
      })
    },


    // 开始轮询训练状态
    startPollingTrainingStatus() {
      if (!this.currentTrainingTask) return

      // 清除之前的定时器
      if (this.trainingStatusTimer) {
        clearInterval(this.trainingStatusTimer)
      }

      // 设置新的定时器，每5秒检查一次状态
      this.trainingStatusTimer = setInterval(() => {
        this.pollTrainingStatus()
      }, 5000)
    },

    // 轮询训练状态
    pollTrainingStatus() {
      if (!this.currentTrainingTask) return

      getTrainingStatus(this.currentTrainingTask.id).then(response => {
        if (response.code === 200) {
          const task = response.data
          this.currentTrainingTask = task
          this.trainingStatus = task.status

          // 更新进度显示
          if (task.status === 'running') {
            // 模拟进度更新，实际应该从日志或任务状态中获取
            if (this.trainingProgress.percentage < 90) {
              this.trainingProgress.percentage += 5
            }
            this.trainingProgress.currentStage = '模型训练中...'
            this.trainingProgress.estimatedTime = '计算中...'
          } else if (task.status === 'completed') {
            this.trainingLoading = false
            this.trainingProgress.percentage = 100
            this.trainingProgress.status = 'success'
            this.trainingProgress.currentStage = '训练完成'
            this.$message.success('模型训练完成！')
            // 停止轮询
            clearInterval(this.trainingStatusTimer)
          } else if (task.status === 'failed') {
            this.trainingLoading = false
            this.trainingProgress.status = 'exception'
            this.trainingProgress.currentStage = '训练失败'
            this.$message.error('训练失败，请查看训练日志')
            // 停止轮询
            clearInterval(this.trainingStatusTimer)
          } else if (task.status === 'stopped') {
            this.trainingLoading = false
            this.trainingProgress.status = 'warning'
            this.trainingProgress.currentStage = '训练已停止'
            this.$message.warning('训练已停止')
            // 停止轮询
            clearInterval(this.trainingStatusTimer)
          }
        }
      }).catch(() => {
        // 出错时不停止轮询，继续尝试
      })
    },

    // 停止训练
    stopTraining(taskId = null) {
      const targetTaskId = taskId || (this.currentTrainingTask ? this.currentTrainingTask.id : null)
      if (!targetTaskId) {
        this.$message.warning('没有正在运行的任务')
        return
      }

      this.$modal.confirm('确认停止训练任务？').then(() => {
        stopTraining(targetTaskId).then(response => {
          if (response.code === 200) {
            this.$message.success('训练任务已停止')
            this.trainingStatus = 'stopped'
            this.trainingLoading = false
            // 停止轮询
            clearInterval(this.trainingStatusTimer)
          } else {
            this.$message.error(response.msg || '停止训练失败')
          }
        }).catch(error => {
          this.$message.error('停止训练失败: ' + (error.message || '未知错误'))
        })
      })
    },

    // 重置训练表单
    resetTrainForm() {
      this.$refs.trainForm.resetFields()
      this.trainForm = {
        taskName: '',
        description: '',
        epochs: 50,
        learningRate: 0.001,
        batchSize: 8,
        modelType: 'ppyoloe_incremental',
        usePretrained: true
      }
      this.trainingProgress.visible = false
      this.trainingStatus = ''
      // 清除轮询定时器
      if (this.trainingStatusTimer) {
        clearInterval(this.trainingStatusTimer)
      }
    },

    // 修改导出标注数据方法
    exportAnnotations() {
      this.exportLoading = true
      const loadingInstance = this.$loading({
        lock: true,
        text: '正在导出标注数据...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });

      exportUserAnnotations().then(response => {
        loadingInstance.close();
        this.exportLoading = false
        if (response.code === 200) {
          this.$message.success('标注数据导出成功')
          this.$alert('标注数据已导出到: ' + response.data, '导出成功', {
            confirmButtonText: '确定'
          });
        } else {
          this.$message.error(response.msg || '导出失败')
        }
      }).catch(error => {
        loadingInstance.close();
        this.exportLoading = false
        this.$message.error('导出失败: ' + (error.message || '未知错误'))
      })
    },

    // 显示训练历史
    showTrainingHistory() {
      this.trainingHistoryVisible = true
      this.historyLoading = true

      getTrainingHistory().then(response => {
        this.historyLoading = false
        if (response.code === 200) {
          this.trainingHistory = response.rows || []
        } else {
          this.$message.error(response.msg || '获取训练历史失败')
        }
      }).catch(() => {
        this.historyLoading = false
        this.$message.error('获取训练历史失败')
      })
    },

    // 获取训练状态标签类型
    getTrainingStatusType(status) {
      const typeMap = {
        'running': 'warning',
        'completed': 'success',
        'failed': 'danger',
        'stopped': 'info'
      }
      return typeMap[status] || 'info'
    },

    // 获取训练状态文本
    getTrainingStatusText(status) {
      const textMap = {
        'running': '训练中',
        'completed': '已完成',
        'failed': '失败',
        'stopped': '已停止'
      }
      return textMap[status] || status
    },

    // 查看训练日志
    viewTrainingLog(task = null) {
      const taskId = task ? task.id : (this.currentTrainingTask ? this.currentTrainingTask.id : null)
      if (!taskId) {
        this.$message.warning('没有可用的训练任务')
        return
      }

      this.currentLogTask = taskId
      this.trainingLogVisible = true
      this.logLoading = true

      getTrainingLog(taskId).then(response => {
        this.logLoading = false
        if (response.code === 200) {
          this.trainingLog = response.data || '暂无日志内容'
        } else {
          this.trainingLog = '获取日志失败: ' + (response.msg || '未知错误')
        }
      }).catch(error => {
        this.logLoading = false
        this.trainingLog = '获取日志失败: ' + (error.message || '未知错误')
      })
    },

    // 刷新训练日志
    refreshTrainingLog() {
      if (!this.currentLogTask) return

      this.logLoading = true
      getTrainingLog(this.currentLogTask).then(response => {
        this.logLoading = false
        if (response.code === 200) {
          this.trainingLog = response.data || '暂无日志内容'
          this.$message.success('日志已刷新')
        } else {
          this.trainingLog = '获取日志失败: ' + (response.msg || '未知错误')
        }
      }).catch(error => {
        this.logLoading = false
        this.trainingLog = '获取日志失败: ' + (error.message || '未知错误')
      })
    },

    // 下载模型
    downloadModel(task) {
      if (!task || task.status !== 'completed') {
        this.$message.warning('该训练任务尚未完成，无法下载模型')
        return
      }

      downloadModel(task.id).then(response => {
        if (response.code === 200) {
          this.$modal.alertSuccess('模型下载信息: ' + response.data)
        } else {
          this.$message.error(response.msg || '下载失败')
        }
      }).catch(error => {
        this.$message.error('下载失败: ' + (error.message || '未知错误'))
      })
    },
    // 修改调试方法
    debugTrainingEnvironment() {
      const loadingInstance = this.$loading({
        lock: true,
        text: '正在调试训练环境...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });

      debugTrainingEnvironment().then(response => {
        loadingInstance.close();
        if (response.code === 200) {
          this.$message.success("调试完成，请查看控制台日志");
          console.log("训练环境调试结果:", response.data);

          // 在页面上显示调试结果
          this.showDebugResult(response.data);
        } else {
          this.$message.error(response.msg || '调试失败');
        }
      }).catch(error => {
        loadingInstance.close();
        this.$message.error('调试失败: ' + error.message);
      });
    },

// 修改测试训练方法
    testSimpleTraining() {
      this.$confirm('这将运行一个简单的训练测试，确认继续？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const loadingInstance = this.$loading({
          lock: true,
          text: '正在运行训练测试...',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });

        testSimpleTraining().then(response => {
          loadingInstance.close();
          if (response.code === 200) {
            this.$message.success("测试训练已启动: " + (response.data.message || ''));
            console.log("测试训练结果:", response.data);
          } else {
            this.$message.error(response.msg || '测试训练失败');
          }
        }).catch(error => {
          loadingInstance.close();
          this.$message.error('测试训练失败: ' + error.message);
        });
      }).catch(() => {
        this.$message.info('已取消测试训练');
      });
    },

// 显示调试结果
    showDebugResult(debugData) {
      // 创建一个新的窗口或对话框来显示详细的调试信息
      const debugWindow = window.open('', '_blank');
      debugWindow.document.write(`
        <html>
            <head>
                <title>训练环境调试结果</title>
                <style>
                    body { font-family: Arial, sans-serif; margin: 20px; }
                    .section { margin-bottom: 20px; border: 1px solid #ddd; padding: 15px; border-radius: 5px; }
                    .success { border-left: 5px solid #67C23A; background-color: #f0f9eb; }
                    .error { border-left: 5px solid #F56C6C; background-color: #fef0f0; }
                    .warning { border-left: 5px solid #E6A23C; background-color: #fdf6ec; }
                    pre { background: #f4f4f4; padding: 10px; border-radius: 3px; overflow: auto; }
                </style>
            </head>
            <body>
                <h1>训练环境调试结果</h1>
                <div id="debugContent"></div>
            </body>
        </html>
    `);

      let content = '';
      for (const [key, value] of Object.entries(debugData)) {
        content += `<div class="section">
            <h3>${key}</h3>
            <pre>${JSON.stringify(value, null, 2)}</pre>
        </div>`;
      }

      debugWindow.document.getElementById('debugContent').innerHTML = content;
      debugWindow.document.close();
    },
    // 修改诊断方法
    diagnoseSystem() {
      const loadingInstance = this.$loading({
        lock: true,
        text: '正在诊断系统...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });

      diagnoseSystem().then(response => {
        loadingInstance.close();
        if (response.code === 200) {
          this.diagnoseResult = response.data;
          this.diagnoseVisible = true;
        } else {
          this.$message.error(response.msg || '诊断失败');
        }
      }).catch(error => {
        loadingInstance.close();
        this.$message.error('诊断失败: ' + error.message);
      });
    },

  }
}
</script>

<style scoped lang="scss">
.app-container {
  padding: 20px;
  background: linear-gradient(135deg, #0a0a0a 0%, #0f0f1a 30%, #0a0a14 70%, #050510 100%);
  min-height: 100vh;
}

.tech-header-glow {
  height: 2px;
  background: linear-gradient(90deg,
    transparent,
    #00ffcc, #00ccff, #ff00cc,
    transparent);
  margin-bottom: 30px;
  animation: headerShimmer 3s infinite;
}

.tech-main-container {
  max-width: 1400px;
  margin: 0 auto;
}

.tech-search-section {
  background: rgba(20, 25, 45, 0.7);
  border: 1px solid rgba(0, 150, 255, 0.2);
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 25px;
  backdrop-filter: blur(10px);

  .search-header {
    display: flex;
    align-items: center;
    margin-bottom: 15px;

    .search-icon {
      font-size: 20px;
      color: #00ccff;
      margin-right: 10px;
    }

    .search-title {
      color: #ccddff;
      margin: 0;
      font-size: 16px;
      font-weight: 600;
    }
  }

  .tech-search-form {
    .search-fields {
      display: flex;
      align-items: center;
      gap: 15px;
      flex-wrap: wrap;
    }
  }
}

.tech-workflow-section {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 25px;
  margin-bottom: 25px;

  @media (max-width: 1200px) {
    grid-template-columns: 1fr;
  }
}

.tech-card {
  background: linear-gradient(135deg, rgba(20, 25, 45, 0.9) 0%, rgba(10, 15, 30, 0.95) 100%);
  border: 1px solid rgba(0, 150, 255, 0.2);
  border-radius: 16px;
  backdrop-filter: blur(10px);
  overflow: hidden;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);

  .card-header-tech {
    background: linear-gradient(135deg, rgba(0, 40, 80, 0.4) 0%, rgba(0, 20, 40, 0.6) 100%);
    border-bottom: 1px solid rgba(0, 150, 255, 0.2);
    padding: 20px 25px;

    .header-content {
      display: flex;
      justify-content: space-between;
      align-items: center;

      .title-section {
        display: flex;
        align-items: center;

        .title-icon {
          font-size: 20px;
          color: #00ccff;
          margin-right: 12px;
        }

        .card-title {
          color: #ccddff;
          margin: 0;
          font-size: 18px;
          font-weight: 600;
        }
      }
    }
  }

  .card-content {
    padding: 25px;
  }
}

.tech-form {
  .form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 20px;
    margin-bottom: 25px;

    @media (max-width: 768px) {
      grid-template-columns: 1fr;
    }
  }

  .form-grid-three {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 20px;
    margin-bottom: 25px;

    @media (max-width: 768px) {
      grid-template-columns: 1fr;
    }
  }

  .form-item {
    .tech-label {
      display: block;
      color: #aaccff;
      font-size: 14px;
      font-weight: 500;
      margin-bottom: 8px;
    }
  }
}

.tech-input-field {
  width: 100%;

  ::v-deep(.el-input__inner) {
    background: rgba(10, 15, 30, 0.6);
    border: 1px solid rgba(0, 150, 255, 0.3);
    border-radius: 8px;
    color: #ccddff;
    transition: all 0.3s ease;

    &:focus {
      border-color: #00ccff;
      box-shadow: 0 0 10px rgba(0, 204, 255, 0.3);
    }

    &::placeholder {
      color: #6677aa;
    }
  }
}

.tech-select-field {
  width: 100%;

  ::v-deep(.el-input__inner) {
    background: rgba(10, 15, 30, 0.6);
    border: 1px solid rgba(0, 150, 255, 0.3);
    border-radius: 8px;
    color: #ccddff;
  }
}

.tech-upload-area {
  background: rgba(10, 15, 30, 0.6);
  border: 2px dashed rgba(0, 150, 255, 0.3);
  border-radius: 12px;
  padding: 40px 20px;
  text-align: center;
  cursor: pointer;
  transition: all 0.3s ease;
  margin-bottom: 15px;

  &:hover {
    border-color: #00ccff;
    background: rgba(0, 40, 80, 0.3);
  }

  .upload-content {
    .upload-main-icon {
      font-size: 48px;
      color: #6677aa;
      margin-bottom: 15px;
      transition: all 0.3s ease;
    }

    .upload-text {
      .upload-main-text {
        color: #ccddff;
        font-size: 16px;
        font-weight: 500;
        margin: 0 0 8px 0;
      }

      .upload-sub-text {
        color: #8899cc;
        font-size: 14px;
        margin: 0;
      }
    }
  }
}

.upload-actions {
  text-align: center;
}

// 按钮样式
.tech-primary-btn {
  background: linear-gradient(135deg, #00ccff, #0099ff);
  border: none;
  border-radius: 8px;
  color: white;
  font-weight: 500;
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(0, 204, 255, 0.4);
  }

  &:disabled {
    background: #6677aa;
    transform: none;
    box-shadow: none;
  }
}

.tech-success-btn {
  background: linear-gradient(135deg, #00ff88, #00cc66);
  border: none;
  border-radius: 8px;
  color: white;
  font-weight: 500;
  transition: all 0.3s ease;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(0, 255, 136, 0.4);
  }
}

.tech-danger-btn {
  background: linear-gradient(135deg, #ff4444, #cc0000);
  border: none;
  border-radius: 8px;
  color: white;
  font-weight: 500;
  transition: all 0.3s ease;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(255, 68, 68, 0.4);
  }
}

.tech-warning-btn {
  background: linear-gradient(135deg, #ffcc00, #ffaa00);
  border: none;
  border-radius: 8px;
  color: white;
  font-weight: 500;
  transition: all 0.3s ease;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(255, 204, 0, 0.4);
  }
}

.tech-info-btn {
  background: linear-gradient(135deg, #6677aa, #556699);
  border: none;
  border-radius: 8px;
  color: white;
  font-weight: 500;
  transition: all 0.3s ease;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(102, 119, 170, 0.4);
  }
}

.tech-secondary-btn {
  background: rgba(102, 119, 170, 0.3);
  border: 1px solid rgba(102, 119, 170, 0.5);
  border-radius: 8px;
  color: #ccddff;
  font-weight: 500;
  transition: all 0.3s ease;

  &:hover {
    background: rgba(102, 119, 170, 0.5);
    border-color: #8899cc;
  }
}

// 标注区域样式
.annotation-content-tech {
  .annotation-controls {
    display: flex;
    align-items: center;
    gap: 15px;
    margin-bottom: 20px;
    padding: 15px;
    background: rgba(10, 15, 30, 0.6);
    border-radius: 8px;

    .annotation-toggle-btn {
      background: rgba(102, 119, 170, 0.3);
      border: 1px solid rgba(102, 119, 170, 0.5);
      border-radius: 8px;
      color: #ccddff;
      transition: all 0.3s ease;

      &.active {
        background: linear-gradient(135deg, #00ff88, #00cc66);
        border-color: #00ff88;
        color: white;
      }

      &:hover {
        transform: translateY(-1px);
      }
    }

    .annotation-status {
      margin-left: auto;
      text-align: right;

      .status-indicator {
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background: #ff4444;
        display: inline-block;
        margin-right: 8px;

        &.active {
          background: #00ff88;
          box-shadow: 0 0 10px #00ff88;
        }
      }

      .status-text {
        color: #ccddff;
        font-size: 14px;
      }

      .status-hint {
        color: #8899cc;
        font-size: 12px;
        margin-top: 4px;
      }
    }
  }
}

.annotation-area-tech {
  .image-container-tech {
    position: relative;
    display: inline-block;
    border-radius: 8px;
    overflow: hidden;
    background: rgba(0, 0, 0, 0.3);

    .annotation-image {
      max-width: 100%;
      max-height: 400px;
      display: block;
    }

    .annotation-canvas-tech {
      position: absolute;
      top: 0;
      left: 0;
      pointer-events: auto;
      cursor: crosshair;
      z-index: 10;
    }
  }
}

.annotation-list-tech {
  margin-top: 25px;

  .list-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;

    h4 {
      color: #ccddff;
      margin: 0;
      display: flex;
      align-items: center;

      i {
        color: #00ccff;
        margin-right: 8px;
      }
    }
  }
}

.tech-table-container {
  ::v-deep(.tech-table) {
    background: transparent;

    .el-table__header-wrapper,
    .el-table__body-wrapper {
      background: rgba(10, 15, 30, 0.6);
    }

    th {
      background: rgba(0, 40, 80, 0.6) !important;
      color: #ccddff !important;
      border-bottom: 1px solid rgba(0, 150, 255, 0.2);
    }

    td {
      background: transparent !important;
      color: #ccddff !important;
      border-bottom: 1px solid rgba(0, 150, 255, 0.1);
    }

    .el-table__row:hover td {
      background: rgba(0, 40, 80, 0.3) !important;
    }
  }

  .index-badge {
    width: 24px;
    height: 24px;
    background: linear-gradient(135deg, #00ccff, #0099ff);
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 600;
    margin: 0 auto;
  }
}

.empty-state-tech {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 200px;

  .empty-content {
    text-align: center;

    .empty-icon {
      font-size: 48px;
      color: #6677aa;
      margin-bottom: 15px;
    }

    h4 {
      color: #ccddff;
      margin: 0 0 8px 0;
    }

    p {
      color: #8899cc;
      margin: 0;
    }
  }
}

// 训练进度样式
.training-progress-tech {
  margin-top: 25px;
  padding: 20px;
  background: rgba(10, 15, 30, 0.6);
  border-radius: 8px;
  border: 1px solid rgba(0, 150, 255, 0.2);

  .progress-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;

    h4 {
      color: #ccddff;
      margin: 0;
      display: flex;
      align-items: center;

      i {
        color: #00ccff;
        margin-right: 8px;
      }
    }

    .progress-percentage {
      color: #00ff88;
      font-size: 18px;
      font-weight: 700;
    }
  }

  .progress-bar-container {
    margin-bottom: 15px;

    .progress-bar {
      width: 100%;
      height: 8px;
      background: rgba(255, 255, 255, 0.1);
      border-radius: 4px;
      overflow: hidden;

      .progress-fill {
        height: 100%;
        border-radius: 4px;
        transition: width 0.5s ease;

        &.success { background: linear-gradient(90deg, #00ff88, #00cc66); }
        &.warning { background: linear-gradient(90deg, #ffcc00, #ffaa00); }
        &.exception { background: linear-gradient(90deg, #ff4444, #cc0000); }
      }
    }
  }

  .progress-info-tech {
    .info-item {
      display: flex;
      margin-bottom: 8px;

      .info-label {
        color: #aaccff;
        width: 120px;
        font-size: 14px;
      }

      .info-value {
        color: #ccddff;
        font-size: 14px;
      }
    }
  }

  .progress-actions {
    margin-top: 15px;
    display: flex;
    gap: 10px;
  }
}

.training-actions {
  display: flex;
  align-items: center;
  gap: 15px;
  flex-wrap: wrap;

  .training-status {
    margin-left: auto;

    .status-tag {
      display: inline-flex;
      align-items: center;
      padding: 6px 12px;
      border-radius: 20px;
      font-size: 12px;
      font-weight: 500;

      .status-dot {
        width: 6px;
        height: 6px;
        border-radius: 50%;
        margin-right: 6px;
      }

      &.running {
        background: rgba(255, 204, 0, 0.2);
        color: #ffcc00;
        .status-dot { background: #ffcc00; }
      }

      &.completed {
        background: rgba(0, 255, 136, 0.2);
        color: #00ff88;
        .status-dot { background: #00ff88; }
      }

      &.failed {
        background: rgba(255, 68, 68, 0.2);
        color: #ff4444;
        .status-dot { background: #ff4444; }
      }

      &.stopped {
        background: rgba(102, 119, 170, 0.2);
        color: #8899cc;
        .status-dot { background: #8899cc; }
      }
    }
  }
}

// 数据管理区域
.tech-data-section {
  margin-top: 30px;

  .section-header-tech {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    padding: 20px;
    background: rgba(20, 25, 45, 0.6);
    border-radius: 16px;
    border: 1px solid rgba(0, 150, 255, 0.2);

    .section-title {
      color: #ccddff;
      margin: 0;
      display: flex;
      align-items: center;
      font-size: 20px;
      font-weight: 600;

      i {
        color: #00ccff;
        margin-right: 12px;
        font-size: 24px;
      }
    }

    .action-buttons-tech {
      display: flex;
      gap: 12px;
    }
  }
}

.tech-table-container {
  margin-bottom: 20px;
}

.tech-data-table {
  background: rgba(20, 25, 45, 0.6) !important;
  border-radius: 16px !important;
  overflow: hidden !important;
  border: 1px solid rgba(0, 150, 255, 0.2) !important;
  backdrop-filter: blur(10px);

  ::v-deep .el-table__body-wrapper {
    &::-webkit-scrollbar {
      width: 6px;
      height: 6px;
    }

    &::-webkit-scrollbar-track {
      background: rgba(255, 255, 255, 0.1);
      border-radius: 3px;
    }

    &::-webkit-scrollbar-thumb {
      background: linear-gradient(135deg, #00ffcc, #00ccff);
      border-radius: 3px;
    }
  }

  ::v-deep .el-table__empty-block {
    background: rgba(15, 20, 40, 0.8);
  }

  ::v-deep .el-table__empty-text {
    color: #8899bb;
  }
}

// 表格单元格样式
.id-cell {
  color: #00ffcc;
  font-weight: 600;
  text-shadow: 0 0 10px rgba(0, 255, 204, 0.5);
}

.disease-cell {
  .disease-name {
    color: #ffffff;
    font-weight: 500;
    padding: 4px 8px;
    background: rgba(0, 255, 204, 0.1);
    border-radius: 6px;
    border: 1px solid rgba(0, 255, 204, 0.3);
  }
}

.crop-cell, .device-cell {
  color: #aaccff;
  font-weight: 500;
}

// 图片单元格样式
.image-cell {
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 80px;

  .image-container {
    position: relative;
    width: 60px;
    height: 60px;
    border-radius: 8px;
    overflow: hidden;
    border: 2px solid rgba(0, 255, 255, 0.3);
    transition: all 0.3s ease;

    &:hover {
      border-color: #00ffcc;
      box-shadow: 0 0 15px rgba(0, 255, 204, 0.5);
      transform: scale(1.05);

      .image-overlay {
        opacity: 1;
      }
    }
  }

  .table-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .image-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.1);
    color: #8899bb;
    font-size: 12px;

    i {
      font-size: 20px;
      margin-bottom: 4px;
    }
  }

  .image-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.7);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.3s ease;

    i {
      color: #00ffcc;
      font-size: 20px;
      text-shadow: 0 0 10px rgba(0, 255, 204, 0.8);
    }
  }

  .image-status {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(0, 0, 0, 0.8);
    color: #ffffff;
    font-size: 10px;
    text-align: center;
    padding: 2px 4px;

    &.annotated {
      background: rgba(0, 255, 102, 0.8);
    }
  }
}

// 标注数量样式
.annotation-count {
  padding: 6px 12px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 600;
  color: #ffffff;
  text-align: center;
  text-shadow: 0 0 5px rgba(255, 255, 255, 0.5);

  &.empty {
    background: linear-gradient(135deg, #6677aa, #556699);
    box-shadow: 0 0 10px rgba(102, 119, 170, 0.5);
  }

  &.medium {
    background: linear-gradient(135deg, #ffcc00, #ff9900);
    box-shadow: 0 0 10px rgba(255, 204, 0, 0.5);
  }

  &.high {
    background: linear-gradient(135deg, #00ff66, #00cc66);
    box-shadow: 0 0 10px rgba(0, 255, 102, 0.5);
  }
}

// 坐标显示样式
.coordinate-display {
  text-align: center;

  .coordinate-item {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 4px;

    .coordinate-label {
      color: #8899bb;
      font-size: 11px;
      margin-right: 4px;
    }

    .coordinate-value {
      color: #00ffcc;
      font-size: 11px;
      font-weight: 500;
      font-family: 'Courier New', monospace;
    }
  }
}

.no-data {
  color: #6677aa;
  font-style: italic;
  font-size: 11px;
}

// 操作按钮样式
.action-buttons {
  display: flex;
  justify-content: center;
  gap: 6px;

  .action-btn {
    background: transparent !important;
    border: none !important;
    color: #aaccff !important;
    padding: 4px 8px !important;
    border-radius: 4px !important;
    transition: all 0.3s ease !important;
    font-size: 12px !important;

    i {
      margin-right: 4px;
    }

    &.view-btn:hover {
      color: #00ccff !important;
      background: rgba(0, 204, 255, 0.1) !important;
      text-shadow: 0 0 8px rgba(0, 204, 255, 0.8);
    }

    &.edit-btn:hover {
      color: #00ff66 !important;
      background: rgba(0, 255, 102, 0.1) !important;
      text-shadow: 0 0 8px rgba(0, 255, 102, 0.8);
    }

    &.delete-btn:hover {
      color: #ff3366 !important;
      background: rgba(255, 51, 102, 0.1) !important;
      text-shadow: 0 0 8px rgba(255, 51, 102, 0.8);
    }

    &.preview-btn:hover {
      color: #ffcc00 !important;
      background: rgba(255, 204, 0, 0.1) !important;
      text-shadow: 0 0 8px rgba(255, 204, 0, 0.8);
    }

    &.add-btn {
      background: linear-gradient(135deg, rgba(0, 255, 204, 0.2), rgba(0, 204, 255, 0.2)) !important;
      border: 1px solid rgba(0, 255, 204, 0.5) !important;
      color: #00ffcc !important;

      &:hover {
        background: linear-gradient(135deg, rgba(0, 255, 204, 0.3), rgba(0, 204, 255, 0.3)) !important;
        box-shadow: 0 0 15px rgba(0, 255, 204, 0.4) !important;
        transform: translateY(-2px);
      }
    }

    &.export-btn {
      background: linear-gradient(135deg, rgba(255, 204, 0, 0.2), rgba(255, 102, 0, 0.2)) !important;
      border: 1px solid rgba(255, 204, 0, 0.5) !important;
      color: #ffcc00 !important;

      &:hover {
        background: linear-gradient(135deg, rgba(255, 204, 0, 0.3), rgba(255, 102, 0, 0.3)) !important;
        box-shadow: 0 0 15px rgba(255, 204, 0, 0.4) !important;
        transform: translateY(-2px);
      }
    }
  }
}

// 分页样式
.pagination-section {
  display: flex;
  justify-content: center;
}

.history-pagination {
  ::v-deep .btn-prev,
  ::v-deep .btn-next,
  ::v-deep .number {
    background: rgba(20, 25, 45, 0.8) !important;
    border: 1px solid rgba(0, 255, 255, 0.3) !important;
    color: #ccddff !important;
    margin: 0 4px;
    border-radius: 6px !important;
    transition: all 0.3s ease !important;

    &:hover {
      border-color: #00ffcc !important;
      color: #00ffcc !important;
      box-shadow: 0 0 10px rgba(0, 255, 204, 0.3) !important;
    }
  }

  ::v-deep .active {
    background: linear-gradient(135deg, #00ffcc, #00ccff) !important;
    border-color: transparent !important;
    color: #0a0a0a !important;
    font-weight: 600 !important;
    box-shadow: 0 0 15px rgba(0, 255, 204, 0.5) !important;
  }
}

// 响应式调整
@media (max-width: 1200px) {
  .tech-data-section .section-header-tech {
    flex-direction: column;
    gap: 15px;
    align-items: stretch;

    .action-buttons-tech {
      justify-content: center;
    }
  }
}

@media (max-width: 768px) {
  .action-buttons {
    flex-direction: column;
    gap: 4px;

    .action-btn {
      justify-content: center;
    }
  }

  .tech-data-table {
    font-size: 12px;
  }
}

// 对话框样式
.tech-dialog {
  ::v-deep(.el-dialog) {
    background: linear-gradient(135deg, rgba(20, 25, 45, 0.95) 0%, rgba(10, 15, 30, 0.98) 100%);
    border: 1px solid rgba(0, 150, 255, 0.2);
    border-radius: 16px;
    color: #ccddff;

    .el-dialog__header {
      background: linear-gradient(135deg, rgba(0, 40, 80, 0.4) 0%, rgba(0, 20, 40, 0.6) 100%);
      border-bottom: 1px solid rgba(0, 150, 255, 0.2);

      .el-dialog__title {
        color: #ccddff;
      }
    }

    .el-dialog__body {
      background: transparent;
    }
  }
}

.log-container-tech {
  max-height: 500px;
  overflow-y: auto;
  background: #1a1a2e;
  color: #00ff88;
  padding: 15px;
  border-radius: 8px;
  font-family: 'Courier New', monospace;
  font-size: 12px;
  line-height: 1.4;
  white-space: pre-wrap;
  word-wrap: break-word;
  border: 1px solid rgba(0, 255, 136, 0.2);
}

@keyframes headerShimmer {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 1; }
}

@media (max-width: 768px) {
  .tech-workflow-section {
    grid-template-columns: 1fr;
  }

  .form-grid,
  .form-grid-three {
    grid-template-columns: 1fr;
  }

  .training-actions {
    flex-direction: column;
    align-items: stretch;

    .training-status {
      margin-left: 0;
      margin-top: 10px;
    }
  }
}
// 添加上传区域有文件时的样式
.tech-upload-area {
  .upload-content {
    &.has-file {
      .upload-main-icon {
        color: #00ff88 !important;
      }
      .upload-main-text {
        color: #00ff88 !important;
      }
    }
  }
}

// 文件预览样式 - 缩小图片尺寸
.file-preview {
  margin-top: 15px;
  padding: 12px;
  background: rgba(10, 15, 30, 0.6);
  border-radius: 8px;
  border: 1px solid rgba(0, 150, 255, 0.2);

  .preview-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;

    span {
      color: #ccddff;
      font-weight: 500;
      font-size: 14px;
    }
  }

  .preview-image-container {
    text-align: center;
    margin-bottom: 10px;

    .preview-image {
      max-width: 100%;
      max-height: 150px; // 缩小预览图片高度
      border-radius: 6px;
      border: 1px solid rgba(0, 255, 255, 0.3);
      object-fit: contain; // 保持图片比例
    }
  }

  .preview-info {
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    padding-top: 10px;

    p {
      margin: 4px 0;
      color: #aaccff;
      font-size: 12px;
      display: flex;
      align-items: center;

      i {
        margin-right: 6px;
        color: #00ccff;
      }

      &.preview-hint {
        color: #ffcc00;
        font-style: italic;
        margin-top: 8px;
        padding: 6px;
        background: rgba(255, 204, 0, 0.1);
        border-radius: 4px;
        border-left: 3px solid #ffcc00;

        i {
          color: #ffcc00;
        }
      }
    }
  }
}

// 标注区域等待状态的特殊提示
.empty-state-tech {
  .upload-status-hint {
    margin-top: 15px;
    padding: 10px;
    background: linear-gradient(135deg, rgba(0, 255, 204, 0.1), rgba(0, 204, 255, 0.1));
    border: 1px solid rgba(0, 255, 204, 0.3);
    border-radius: 6px;
    color: #00ffcc;
    font-size: 13px;
    display: flex;
    align-items: center;
    justify-content: center;

    i {
      margin-right: 6px;
      font-size: 14px;
    }
  }
}

// 上传按钮区域调整
.upload-actions {
  display: flex;
  gap: 10px;
  margin-top: 15px;

  .tech-primary-btn, .tech-secondary-btn {
    flex: 1;
    height: 36px;
  }
}

.upload-actions {
  display: flex;
  gap: 10px;
  margin-top: 15px;

  .tech-primary-btn, .tech-secondary-btn {
    flex: 1;
  }
}
</style>

<!-- 全局样式 -->
<style>
.tech-search-btn {
  background: linear-gradient(135deg, #00ccff, #0099ff) !important;
  border: none !important;
  color: white !important;
  border-radius: 6px !important;
}

.tech-reset-btn {
  background: rgba(102, 119, 170, 0.3) !important;
  border: 1px solid rgba(102, 119, 170, 0.5) !important;
  color: #ccddff !important;
  border-radius: 6px !important;
}

.clear-btn-tech,
.history-btn-tech {
  color: #8899cc !important;
  background: transparent !important;
  border: none !important;
}

.clear-btn-tech:hover,
.history-btn-tech:hover {
  color: #00ccff !important;
}

.tech-input .el-input__inner {
  background: rgba(10, 15, 30, 0.6) !important;
  border: 1px solid rgba(0, 150, 255, 0.3) !important;
  border-radius: 6px !important;
  color: #ccddff !important;
}

.tech-input .el-input__inner:focus {
  border-color: #00ccff !important;
  box-shadow: 0 0 8px rgba(0, 204, 255, 0.3) !important;
}

.tech-select .el-input__inner {
  background: rgba(10, 15, 30, 0.6) !important;
  border: 1px solid rgba(0, 150, 255, 0.3) !important;
  border-radius: 6px !important;
  color: #ccddff !important;
}

.tech-tabs .el-tabs__item {
  color: #8899cc !important;
}

.tech-tabs .el-tabs__item.is-active {
  color: #00ccff !important;
}

.tech-tabs .el-tabs__active-bar {
  background-color: #00ccff !important;
}

.image-slot-tech {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  background: rgba(10, 15, 30, 0.6);
  color: #8899cc;
  border-radius: 4px;
}
</style>
